from random import random

class Perceptron(object):
    
    def __init__(self, inputs_count, outputs_count):
        self._inputs = [0 for x in xrange(inputs_count)]
        self._outputs = [0 for x in xrange(outputs_count)]
        self._weights = []
        self._limit_activation = 1
        self._rate_training = 0.1
        self._limit_training = 1000

        for i in xrange(outputs_count):
            self._weights.append([])
            for j in xrange(inputs_count):
                self._weights[i].append(random() / 10)
                
    @property
    def inputs(self):
        """Get inputs"""
        return self._inputs
    
    @property
    def outputs(self):
        """Get outputs"""
        return self._outputs
    
    @property    
    def weights(self):
        """Get weights"""
        return self._weights


    def call(self, image):
        if len(image) != len(self.inputs):
            raise ImageError
        self._inputs = [x for x in image]
        for i in xrange(len(self._outputs)):
            s = 0
            for j in xrange(len(self._inputs)):
                s += self._weights[i][j] * self._inputs[i]
            if s > self._limit_activation: 
                self._outputs[i] = 1
            else:
                self._outputs[i] = 0
        return self._outputs

    def remember(self, image, out):
        if len(image) != len(self.inputs):
            raise ImageError
        count = self._limit_training
        while count != 0:
            count -= 1 
            self.call(image)
            if self._outputs == out: break
            err = map(lambda x,y: x-y, out, self._outputs)
            for i in xrange(len(self._outputs)):
                for j in xrange(len(self._inputs)):
                    self._weights[i][j] += self._rate_training * err[i] * image[j]
        else:
            raise RememberError
                


class ImageError(Exception):
    pass
        
class RememberError(Exception):
    pass
        
